package org.geometerplus.fbreader.library;

import java.lang.ref.SoftReference;
import java.util.HashMap;

import org.geometerplus.android.fbreader.RLog;
import org.zixuanstudio.ebook.R;

import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;

public class BookCoverCache {
	private HashMap<Long, SoftReference<Drawable>> imageCache = new HashMap<Long, SoftReference<Drawable>>();

	private static BookCoverCache mInstance = null;

	private BookCoverCache() {
	}

	public static BookCoverCache getInstance() {
		if (mInstance == null) {
			mInstance = new BookCoverCache();
		}
		return mInstance;
	}

	public Drawable get(Cursor cursor) {
		long bookId = cursor.getLong(0);
		byte[] data = cursor.getBlob(4);
		RLog.v("BookCoverCache", "bookId=" + bookId);
		if (imageCache.containsKey(bookId)) {
			Drawable drawable = imageCache.get(bookId).get();
			if (drawable != null) {
				return drawable;
			} else {
				try {
					/**
					 * android系统中读取位图Bitmap时.分给虚拟机中图片的堆栈大小只有8M。 所以不管是如何调用的图片，
					 * 太多太大虚拟机肯定会报那个错误。
					 * 超出图片内存预算那个错误.:java.lang.OutOfMemoryError: bitmap size
					 * exceeds VM budget
					 * 
					 */
					drawable = createThumbnailDrawable(data);
					if (drawable != null)
					imageCache.put(bookId,
							new SoftReference<Drawable>(drawable));
					return drawable;
				} catch (OutOfMemoryError err) {
					return null;
				}

			}
		} else {
			try {
				Drawable drawable = createThumbnailDrawable(data);
				if (drawable != null)
				imageCache.put(bookId, new SoftReference<Drawable>(drawable));
				return drawable;
			} catch (Exception e) {
				return null;
			}
		}
	}

	/**
	 * 为图书封面生成缩略图
	 * @param data
	 * @return
	 */
	private  Drawable createThumbnailDrawable(byte[] data) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.outHeight = 150;
		//options.inTempStorage = new byte[1024 * 1024 * 7];
		options.inJustDecodeBounds = true;
	//	options.inTempStorage= new byte[1024*1024*5];//5M缓存空间
		// options.
		Bitmap bm = BitmapFactory
				.decodeByteArray(data, 0, data.length, options); // 此时返回bm为空
		options.inJustDecodeBounds = false;
		int be = options.outHeight / 200;
		if (be % 10 != 0)
			be += 10;
		be = be / 10;
		if (be <= 0)
			be = 1;
		options.inSampleSize = be;
		try {
			bm =  BitmapFactory.decodeByteArray(data, 0, data.length, options);
		} catch (OutOfMemoryError  e) {
			e.printStackTrace();
		} // 此时返回bm为空
		return new BitmapDrawable(bm);
	}
}
